package v1

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"melon/server/constant"
	"melon/server/global"
	"melon/server/middleware/authorization"
	"melon/server/model"
	userstoken "melon/server/service/user_service"
	"melon/server/utils/response"
	"strconv"
	"strings"
	"time"
)

type UserInfo struct {
}

type ResetRequest struct {
	Id       string `json:"id"`
	Original string `json:"original"`
	Password string `json:"password"`
	Confirm  string `json:"confirm"`
}

type UpdateRequest struct {
	Id       string `json:"id"`
	NickName string `json:"nickname"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
	Remark   string `json:"intro"`
	Sex      string `json:"sex"`
}

func (v *UserInfo) Login(context *gin.Context) {
	var req model.UsersLogin
	// 绑定参数
	if err := context.ShouldBindJSON(&req); err != nil {
		response.Fail(context, constant.ValidatorParamsCheckFailCode, constant.ValidatorParamsCheckFailMsg, "")
	}
	userModel := model.CreateUserFactory("").Login(req.UserName, req.Pass)

	if userModel != nil {
		userTokenFactory := userstoken.CreateUserFactory()
		if userToken, err := userTokenFactory.GenerateToken(userModel.Id, userModel.UserName, userModel.Phone,
			global.ConfigYml.GetInt64("Token.JwtTokenCreatedExpireAt")); err == nil {
			if userTokenFactory.RecordLoginToken(userToken, context.ClientIP()) {
				data := gin.H{
					"userId":     userModel.Id,
					"user_name":  req.UserName,
					"realName":   userModel.RealName,
					"phone":      "",
					"token":      userToken,
					"updated_at": time.Now().Format(global.DateFormat),
				}
				response.Success(context, constant.CurdStatusOkMsg, data)
				return
			}
		}
	}
	response.Fail(context, constant.CurdLoginFailCode, constant.CurdLoginFailMsg, "")
}

func (v *UserInfo) Logout(context *gin.Context) {
	data := model.LoginResponse{Token: ""}
	response.Success(context, constant.CurdStatusOkMsg, data)
}

func getUserIdFromToken(headerParams *authorization.HeaderParams) (userId int64) {
	if len(headerParams.Authorization) >= 20 {
		token := strings.Split(headerParams.Authorization, " ")
		if len(token) == 2 && len(token[1]) >= 20 {
			if customToken, err := userstoken.CreateUserFactory().ParseToken(token[1]); err == nil {
				userId = customToken.UserId
			}
		}
	}
	return
}

func (u *UserInfo) Current(context *gin.Context) {

	headerParams := authorization.HeaderParams{}
	//  推荐使用 ShouldBindHeader 方式获取头参数
	if err := context.ShouldBindHeader(&headerParams); err != nil {
		global.ZapLog.Error(constant.ErrorsValidatorBindParamsFail, zap.Error(err))
	}

	userId := getUserIdFromToken(&headerParams)
	user, err := userstoken.CreateUserCurdFactory().ShowUser(userId)
	if err == nil {
		response.Success(context, constant.CurdStatusOkMsg, user)
	} else {
		response.Fail(context, constant.CurdSelectFailCode, constant.CurdSelectFailMsg, "")
	}
}

func (u *UserInfo) Reset(context *gin.Context) {

	var req ResetRequest
	id := context.Param("id")
	if err := context.ShouldBindJSON(&req); err != nil {
		global.ZapLog.Error(constant.ErrorsValidatorBindParamsFail, zap.Error(err))
	}

	if reset := userstoken.CreateUserCurdFactory().ResetPass(id, req.Original, req.Password); reset {
		response.Success(context, constant.CurdStatusOkMsg, "")
	} else {
		response.Fail(context, constant.CurdResetPassFailCode, constant.CurdResetPassFailMsg, "")
	}
}

func (u *UserInfo) Update(context *gin.Context) {

	var req UpdateRequest
	if err := context.ShouldBindJSON(&req); err != nil {
		global.ZapLog.Error(constant.ErrorsValidatorBindParamsFail, zap.Error(err))
	}

	idInt, _ := strconv.ParseInt(req.Id, 10, 64)
	sexInt, _ := strconv.Atoi(req.Sex)
	if update := userstoken.CreateUserCurdFactory().Update(idInt, req.NickName, req.Phone, req.Email, req.Remark, sexInt); update {
		response.Success(context, constant.CurdStatusOkMsg, "")
	} else {
		response.Fail(context, constant.CurdResetPassFailCode, constant.CurdResetPassFailMsg, "")
	}

}
